package com.example.questionsystem.modules.qu.service.impl;// Service 层实现
import net.lingala.zip4j.io.outputstream.ZipOutputStream;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.model.enums.AesKeyStrength;
import net.lingala.zip4j.model.enums.EncryptionMethod;
import org.apache.commons.compress.archivers.zip.Zip64Mode;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.List;

@Service
public class ZipService {
    
    public void createEncryptedZipFromDir(
            Path sourceDir,
            OutputStream outputStream,
            String password
    ) throws IOException {
        
        ZipParameters zipParameters = buildZipParameters(password);
        zipParameters.setEncryptionMethod(EncryptionMethod.ZIP_STANDARD);
        try (ZipOutputStream zos = new ZipOutputStream(outputStream, password.toCharArray())) {
            Files.walkFileTree(sourceDir, new SimpleFileVisitor<Path>() {
                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                    addFileToZip(zos, zipParameters, sourceDir, file);
                    return FileVisitResult.CONTINUE;
                }
            });
        }
    }
    public void createEncryptedZipFromDirs(
            List<Path> sourceDirs,
            OutputStream outputStream,
            String password
    ) throws IOException {

        ZipParameters zipParameters = buildZipParameters(password);
        zipParameters.setEncryptionMethod(EncryptionMethod.ZIP_STANDARD);

        try (ZipOutputStream zos = new ZipOutputStream(outputStream, password.toCharArray())) {
            for (Path sourceDir : sourceDirs) {
                Files.walkFileTree(sourceDir, new SimpleFileVisitor<Path>() {
                    @Override
                    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                        // 保持每个目录的原始结构
                        String entryName = sourceDir.getParent().relativize(file).toString().replace("\\", "/");
                        zipParameters.setFileNameInZip(entryName);

                        zos.putNextEntry(zipParameters);
                        Files.copy(file, zos);
                        zos.closeEntry();
                        return FileVisitResult.CONTINUE;
                    }

                    @Override
                    public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                        // 创建目录条目
                        if (!dir.equals(sourceDir)) {
                            String entryName = sourceDir.getParent().relativize(dir).toString().replace("\\", "/") + "/";
                            zipParameters.setFileNameInZip(entryName);
                            zos.putNextEntry(zipParameters);
                            zos.closeEntry();
                        }
                        return FileVisitResult.CONTINUE;
                    }
                });
            }
        }
    }

    private ZipParameters buildZipParameters(String password) {
        ZipParameters parameters = new ZipParameters();
        parameters.setEncryptFiles(password != null && !password.isEmpty());
        if (parameters.isEncryptFiles()) {
            parameters.setEncryptionMethod(EncryptionMethod.AES);
            parameters.setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_256);
        }
        return parameters;
    }

    private void addFileToZip(ZipOutputStream zos,
                             ZipParameters parameters,
                             Path baseDir,
                             Path file) throws IOException {
        // 保持目录结构
        String entryName = baseDir.relativize(file).toString().replace("\\", "/");
        parameters.setFileNameInZip(entryName);
        
        zos.putNextEntry(parameters);
        Files.copy(file, zos);
        zos.closeEntry();
    }
}